﻿using System.Diagnostics;
using System.IO;
using UnityEditor;
using UnityEngine;
using winS.Unity.Serialization;
using Debug = UnityEngine.Debug;

namespace winS.UnityEditor
{
    /// <summary>
    /// Provides data saving function base on <see cref="EditorWindow"/>.
    /// </summary>
    public abstract class DataEditorWindow<T> : EditorWindow where T : new()
    {
        /// <summary>
        /// Editor data of the EditorWindow.
        /// </summary>
        public T editorData { get; private set; }

        protected Serializer serializer { get; private set; }
        protected Deserializer deserializer { get; private set; }

        private string editorDataFilePath;

        internal override void OnEnable()
        {
            serializer = new Serializer();
            deserializer = new Deserializer();
            editorDataFilePath = $"{Editor.projectEditorWindowDataLocalDirectory}/{GetType().FullName}";
            LoadEditorData();
            base.OnEnable();
        }

        public sealed override void SaveWindow()
        {
            SaveEditorData();
            base.SaveWindow();
        }

        protected bool LoadEditorData()
        {
            if (TryLoadData()) return true;
            editorData = new T();
            Debug.LogWarning($"{GetType().Name}.{nameof(LoadEditorData)}: 加载编辑器窗口数据 {typeof(T).Name} 失败, 已使用默认数据");
            return false;
        }
        protected void SaveEditorData()
        {
            serializer.Serialize(editorData, editorDataFilePath);
        }
        protected override void AddItemsToMenu(GenericMenu genericMenu)
        {
            base.AddItemsToMenu(genericMenu);
            genericMenu.AddItem(new GUIContent("打开数据存放目录"), false, () => Process.Start(Editor.projectEditorWindowDataLocalDirectory));
        }

        private bool TryLoadData()
        {
            if (!Directory.Exists(Editor.projectEditorWindowDataLocalDirectory))
            {
                Directory.CreateDirectory(Editor.projectEditorWindowDataLocalDirectory);
                return false;
            }
            if (!File.Exists(editorDataFilePath)) return false;

            try { editorData = deserializer.DeserializeFromFile<T>(editorDataFilePath); }
            catch { return false; }
            return true;
        }
    }
}